package com.bingxue.edu.management.listener;

import cn.hutool.core.util.StrUtil;
import com.bingxue.edu.common.enums.ClassCategoryEnum;
import com.bingxue.edu.common.enums.CommonStatusEnum;
import com.bingxue.edu.common.enums.ReceiveTypeEnum;
import com.bingxue.edu.management.education.service.EnrollmentService;
import com.bingxue.edu.management.event.RecommenderSetEvent;
import com.bingxue.edu.management.shop.activity.ActivityConstants;
import com.bingxue.edu.management.shop.activity.ActivityUtil;
import com.bingxue.edu.management.shop.activity.LdxActivityConfig;
import com.bingxue.edu.management.shop.model.entity.Activity;
import com.bingxue.edu.management.shop.model.req.CouponDistributeReq;
import com.bingxue.edu.management.shop.service.ActivityService;
import com.bingxue.edu.management.shop.service.CouponService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;

import static com.bingxue.edu.management.education.model.entity.table.ClassInfoTableDef.CLASS_INFO;
import static com.bingxue.edu.management.education.model.entity.table.EnrollmentTableDef.ENROLLMENT;
import static com.bingxue.edu.management.education.model.entity.table.StudentTableDef.STUDENT;

/**
 * 设置推荐人后，立即给新用户发放优惠券
 * @author panbo
 * @since 2024/11/13
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class RecommenderSetEventListener {

    private final ActivityService activityService;
    private final EnrollmentService enrollmentService;
    private final CouponService couponService;

    @Async
    @TransactionalEventListener(fallbackExecution = true)
    public void onEventListen(RecommenderSetEvent event) {
        String parentId = event.getParentId();
        String parentPhone = event.getParentPhone();
        String recommenderPhone = event.getRecommenderPhone();

        // 1. 判断活动是否开启
        Activity activity = activityService.getByCode(ActivityConstants.LDX_CODE);
        if (activity.getStatus() != CommonStatusEnum.ENABLED) {
            log.debug("老带新活动未开启，跳过新用户优惠券发放");
            return;
        }

        // 2. 判断使用条件
        // 是否为新用户
        if (!isNewUser(parentPhone)) {
            log.debug("手机号[{}]不是新用户，跳过新用户优惠券发放", parentPhone);
            return;
        }

        // 2. 获取活动配置
        LdxActivityConfig config = ActivityUtil.getActivityConfig(activity, LdxActivityConfig.class);
        if (StrUtil.isEmpty(config.getNewUserCouponTemplateId())) {
            log.warn("老带新活动配置-新用户赠送优惠券id[{}]不存在，跳过新用户优惠券发放", config.getNewUserCouponTemplateId());
            return;
        }

        // 3. 新用户发放优惠券
        CouponDistributeReq couponDistributeReq = new CouponDistributeReq();
        couponDistributeReq.setParentId(parentId);
        couponDistributeReq.setCouponTemplateId(config.getNewUserCouponTemplateId());
        couponDistributeReq.setReceiveType(ReceiveTypeEnum.BACKEND);
        for (int i = 0; i < config.getNewUserCouponCount(); i++) {
            couponService.distributeCoupon(couponDistributeReq);
        }

        log.info("老带新活动-新用户优惠券发放成功，新用户: {}, 老用户: {}, 发放数量: {}",
                parentPhone,
                recommenderPhone,
                config.getNewUserCouponCount()
        );

    }

    /**
     * 根据手机号判断家长是否为新用户
     * 判断依据：家长不存在长期班的报名记录
     * @param parentMobile 家长手机
     * @return 是否为新用户
     */
    boolean isNewUser(String parentMobile) {
        return !enrollmentService.queryChain()
                .leftJoin(STUDENT).on(STUDENT.ID.eq(ENROLLMENT.STUDENT_ID))
                .leftJoin(CLASS_INFO).on(CLASS_INFO.ID.eq(ENROLLMENT.CLASS_ID))
                .where(STUDENT.PARENT_PHONE.eq(parentMobile))
                .and(CLASS_INFO.CLASS_CATEGORY.eq(ClassCategoryEnum.LONG_TERM_CLASS))
                .exists();
    }
}
